/*---------------------------------------------------------------------------*\
 This file is part of the Fab@Home Project.
 Fab@Home operates under the BSD Open Source License.

 Copyright (c) 2009, Karl Gluck (kwg8@cornell.edu)
 
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
     * Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
     * Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.
     * Neither the name of the <organization> nor the
       names of its contributors may be used to endorse or promote products
       derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNERS OR CONTRIBUTORS BE LIABLE
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\*---------------------------------------------------------------------------*/
#pragma once

#include "pathslice.h"
#include "shared/slicer/slicestack.h"

/**
 * Stores all of the tool-paths that make up the print of a 3d model
 */
typedef QVector<PathSlice*> PathSliceArray;

/**
 * PathStack serves as a container for all of the pathed slices of a given
 * object, and is the base form of how pathing is represented for an object.
 * PathStack contains all PathSlices, which contain PathMaterials, which
 * contain PathRegions, which then contain the paths themselves.
 */
class PathStack {
public:

  ~PathStack();

  /**
   * Returns a reference to the array of PathSlices
   * @return reference to a PathSliceArray
   */
  const PathSliceArray& getPathSlices() const;

  /**
   * Outputs the contents of this path stack to an XML file that is
   * readable by a human and can be examined by another program for
   * correctness.
   */ 
  bool writeToXMLFile(const QString& file_name) const;

  /**
   * Outputs the contents of this path stack to an ASCII text
   * file that can be interpreted by the path visualizer program.
   */
  bool writeToVisualizerFile(const QString& file_name) const;

  /**
   * This PathStack can validate itself against the source 3d model to make
   * sure that it provides a good representation and is reasonable for
   * printing.
   *
   * Tests include:
   *  - how much (%) of the total 3d model is filled with material
   *  - does any path cross another path within a single layer
   *
   * Any null parameter is ignored.
   * @param overall_coverage What portion [0, 1] of the new model is filled
   *                         with material by the paths?
   * @param path_length What is the total length of all of the paths?
   * @param print_length pathLength plus the distance between consecutive
   *                    paths' start/end coordinates.
   * @param self_intersecting Are there one or more self-intersecting paths?
   */
  void getStatistics(const SliceStack& source,
                     float* overall_coverage,
                     float* path_length,
                     float* print_length,
                     bool* self_intersecting) const;

  /**
   * Sorts the paths within each slice such that the total distance over
   * between one path's end and the next path's start is minimized.  This
   * should reduce print time by lowering the "dead" time between printing
   * paths.
   * It is expected that the printLength statistic will decrease from what
   * it was previous to calling this function the first time, thus decreasing
   * the total duration of the print job.
   * @todo This method is not implemented.
   */
  void optimizePathOrder();

  /**
   * Appends a slice to this stack.  The slice must be allocated with 'new'
   * and not used anywhere else.  The memory will be freed when this class
   * is deallocated.
   */
  void addSlice(PathSlice* slice);

private:

  PathSliceArray slices_; /// contains all of the slices generated by the slicer
                          /// that makes up this object
};
